using System;
using System.Collections.Generic;
using System.Drawing;
using ZoneFiveSoftware.Common.Data.Measurement;
using ZoneFiveSoftware.Common.Data.Fitness;
using ZoneFiveSoftware.Common.Visuals;
using FilteredStatistics.Controller;
using FilteredStatistics.View;

namespace FilteredStatistics.Data
{
    class FilteredStatisticsStatProvider
    {
        public FilteredStatisticsStatProvider()
        {
        }

#region IStatProvider members

        public String GetStatisticText(Guid columnId, object currentRange)
        {
            return String.Empty;
        }

        public String GetTotalStatisticText(Guid columnId, List<object> allRanges)
        {
            if (allRanges.Count > 0)
            {
                m_AllRanges.Clear();
                foreach (RangeWrapper wrapper in allRanges)
                {
                    m_AllRanges.Add(wrapper);
                }

                return String.Empty;
            }

            return String.Empty;
        }

#endregion

#region Single range stats

        public TimeSpan GetStartTimeValue(RangeWrapper range)
        {
            return range.PauselessRange.Lower - range.ActivityInfo.ActualTrackStart;
        }

        public String GetStartTime(RangeWrapper range)
        {
            TimeSpan startTime = GetStartTimeValue(range);

            return String.Format("{0:00}:{1:00}:{2:00}", startTime.Hours, startTime.Minutes, startTime.Seconds);
        }

        public TimeSpan GetEndTimeValue(RangeWrapper range)
        {
            return range.PauselessRange.Upper - range.ActivityInfo.ActualTrackStart;
        }

        public String GetEndTime(RangeWrapper range)
        {
            TimeSpan endTime = GetEndTimeValue(range);

            return String.Format("{0:00}:{1:00}:{2:00}", endTime.Hours, endTime.Minutes, endTime.Seconds);
        }

        public double GetStartDistanceValue(RangeWrapper range)
        {
            return Length.Convert(range.RangeDistanceTrack.Min, Length.Units.Meter, range.Activity.Category.DistanceUnits);
        }

        public String GetStartDistance(RangeWrapper range)
        {
            return String.Format("{0:0.0} {1}", GetStartDistanceValue(range), Length.LabelAbbr(range.Activity.Category.DistanceUnits));
        }

        public double GetEndDistanceValue(RangeWrapper range)
        {
            return Length.Convert(range.RangeDistanceTrack.Max, Length.Units.Meter, range.Activity.Category.DistanceUnits);
        }

        public String GetEndDistance(RangeWrapper range)
        {
            return String.Format("{0:0.0} {1}", GetEndDistanceValue(range), Length.LabelAbbr(range.Activity.Category.DistanceUnits));
        }

        public TimeSpan GetElapsedTimeValue(RangeWrapper range)
        {
            return range.PauselessRange.Upper - range.PauselessRange.Lower;
        }

        public String GetElapsedTime(RangeWrapper range)
        {
            TimeSpan elapsedTime = GetElapsedTimeValue(range);

            return String.Format("{0:00}:{1:00}:{2:00}", elapsedTime.Hours, elapsedTime.Minutes, elapsedTime.Seconds);
        }

        public double GetDistanceValue(RangeWrapper range)
        {
            if (range.RangeDistanceTrack.Count > 0)
            {
                return Length.Convert(range.RangeDistanceTrack.Max - range.RangeDistanceTrack.Min, Length.Units.Meter, range.Activity.Category.DistanceUnits);
            }

            return 0;
        }

        public String GetDistance(RangeWrapper range)
        {
            if (range.RangeDistanceTrack.Count > 0)
            {
                return String.Format("{0:0.00} {1}", GetDistanceValue(range), Length.LabelAbbr(range.Activity.Category.DistanceUnits));
            }

            return String.Empty;
        }

        public double GetTimePercentValue(RangeWrapper range)
        {
            if (Utils.GetActiveActivityTime(range.Activity).TotalMilliseconds != 0)
            {
                TimeSpan elapsedTime = range.PauselessRange.Upper - range.PauselessRange.Lower;
                return elapsedTime.TotalSeconds / range.ActivityInfo.Time.TotalSeconds;
            }

            return 0;
        }

        public String GetTimePercent(RangeWrapper range)
        {
            if (range.ActivityInfo.Time.TotalMilliseconds != 0)
            {
                return String.Format("{0:0.00} %", GetTimePercentValue(range) * 100.0);
            }

            return String.Empty;
        }

        public double GetDistancePercentValue(RangeWrapper range)
        {
            if (range.RangeDistanceTrack.Max > 0)
            {
                double rangeDistance = range.RangeDistanceTrack.Max - range.RangeDistanceTrack.Min;

                return rangeDistance / range.ActivityDistanceTrack.Max;
            }

            return 0;
        }

        public String GetDistancePercent(RangeWrapper range)
        {
            if (range.RangeDistanceTrack.Max > 0 && range.RangeDistanceTrack.Max != range.RangeDistanceTrack.Min)
            {
                return String.Format("{0:0.00} %", GetDistancePercentValue(range) * 100.0);
            }

            return String.Empty;
        }

        public double GetElevationChangeValue(RangeWrapper range)
        {
            if (range.RangeElevationTrack.Count > 0)
            {
                return GetEndElevationValue(range) - GetStartElevationValue(range);
            }

            return 0;
        }

        public String GetElevationChange(RangeWrapper range)
        {
            if (range.RangeElevationTrack.Count > 0)
            {
                String sign = String.Empty;
                double value = GetElevationChangeValue(range);

                if (value < 0)
                {
                    sign = "-";
                }
                else if (value > 0)
                {
                    sign = "+";
                }

                return String.Format("{2}{0:0.0} {1}", Math.Abs(value), Length.LabelAbbr(range.Activity.Category.ElevationUnits), sign);
            }

            return String.Empty;
        }

        public double GetStartElevationValue(RangeWrapper range)
        {
            if (range.RangeElevationTrack.Count > 0)
            {
                return Length.Convert(range.RangeElevationTrack[0].Value, Length.Units.Meter, range.Activity.Category.ElevationUnits);
            }

            return 0;
        }

        public String GetStartElevation(RangeWrapper range)
        {
            if (range.RangeElevationTrack.Count > 0)
            {
                String sign = String.Empty;

                if (GetStartElevationValue(range) < 0)
                {
                    sign = "-";
                }

                return String.Format("{2}{0:0.0} {1}", Math.Abs(Math.Round(GetStartElevationValue(range), 1)), Length.LabelAbbr(range.Activity.Category.ElevationUnits), sign);
            }

            return String.Empty;
        }

        public double GetEndElevationValue(RangeWrapper range)
        {
            if (range.RangeElevationTrack.Count > 0)
            {
                return Length.Convert(range.RangeElevationTrack[range.RangeElevationTrack.Count - 1].Value, Length.Units.Meter, range.Activity.Category.ElevationUnits);
            }

            return 0;
        }

        public String GetEndElevation(RangeWrapper range)
        {
            if (range.RangeElevationTrack.Count > 0)
            {
                String sign = String.Empty;

                if (GetEndElevationValue(range) < 0)
                {
                    sign = "-";
                }

                return String.Format("{2}{0:0.0} {1}", Math.Abs(Math.Round(GetEndElevationValue(range), 1)), Length.LabelAbbr(range.Activity.Category.ElevationUnits), sign);
            }

            return String.Empty;
        }

        public double GetTotalAscentValue(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                ZoneCategoryInfo categoryInfo = ZoneCategoryInfo.Calculate(range.ActivityInfo, PluginMain.GetApplication().DisplayOptions.SelectedClimbZone, range.RangeGradeTrack, 100.0f);
                double totalAscent = 0;

                // Remove totals row
                categoryInfo.Zones.RemoveAt(categoryInfo.Zones.Count - 1);

                foreach (ZoneInfo zoneInfo in categoryInfo.Zones)
                {
                    if (zoneInfo.Zone.Low > 0)
                    {
                        totalAscent += zoneInfo.ElevationChangeMeters;
                    }
                }

                return Length.Convert(totalAscent, Length.Units.Meter, range.Activity.Category.ElevationUnits);
            }

            return 0;
        }

        public String GetTotalAscent(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                return String.Format("{0:0.0} {1}", Math.Round(GetTotalAscentValue(range), 1), Length.LabelAbbr(range.Activity.Category.ElevationUnits));
            }

            return String.Empty;
        }

        public double GetTotalDescentValue(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                ZoneCategoryInfo categoryInfo = ZoneCategoryInfo.Calculate(range.ActivityInfo, PluginMain.GetApplication().DisplayOptions.SelectedClimbZone, range.RangeGradeTrack, 100.0f);
                double totalDescent = 0;

                // Remove totals row
                categoryInfo.Zones.RemoveAt(categoryInfo.Zones.Count - 1);

                foreach (ZoneInfo zoneInfo in categoryInfo.Zones)
                {
                    if (zoneInfo.Zone.High < 0)
                    {
                        totalDescent += zoneInfo.ElevationChangeMeters;
                    }
                }

                return Math.Abs(Length.Convert(m_TotalDescent, Length.Units.Meter, range.Activity.Category.ElevationUnits));
            }

            return 0;
        }

        public String GetTotalDescent(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                return String.Format("{0:0.0} {1}", Math.Round(GetTotalDescentValue(range), 1), Length.LabelAbbr(range.Activity.Category.ElevationUnits));
            }

            return String.Empty;
        }

        public double GetAscentDistanceValue(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                ZoneCategoryInfo categoryInfo = ZoneCategoryInfo.Calculate(range.ActivityInfo, PluginMain.GetApplication().DisplayOptions.SelectedClimbZone, range.RangeGradeTrack, 100.0f);
                double totalAscentDistance = 0;

                // Remove totals row
                categoryInfo.Zones.RemoveAt(categoryInfo.Zones.Count - 1);

                foreach (ZoneInfo zoneInfo in categoryInfo.Zones)
                {
                    if (zoneInfo.Zone.Low > 0)
                    {
                        totalAscentDistance += zoneInfo.TotalDistanceMeters;
                    }
                }

                return Length.Convert(totalAscentDistance, Length.Units.Meter, range.Activity.Category.DistanceUnits);
            }

            return 0;
        }

        public String GetAscentDistance(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                return String.Format("{0:0.00} {1}", Math.Round(GetAscentDistanceValue(range), 2), Length.LabelAbbr(range.Activity.Category.DistanceUnits));
            }

            return String.Empty;
        }

        public double GetFlatDistanceValue(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                ZoneCategoryInfo categoryInfo = ZoneCategoryInfo.Calculate(range.ActivityInfo, PluginMain.GetApplication().DisplayOptions.SelectedClimbZone, range.RangeGradeTrack, 100.0f);
                double totalFlatDistance = 0;

                // Remove totals row
                categoryInfo.Zones.RemoveAt(categoryInfo.Zones.Count - 1);

                foreach (ZoneInfo zoneInfo in categoryInfo.Zones)
                {
                    if (zoneInfo.Zone.Low < 0 && zoneInfo.Zone.High > 0)
                    {
                        totalFlatDistance += zoneInfo.TotalDistanceMeters;
                    }
                }

                return Length.Convert(totalFlatDistance, Length.Units.Meter, range.Activity.Category.DistanceUnits);
            }

            return 0;
        }

        public String GetFlatDistance(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                return String.Format("{0:0.00} {1}", Math.Round(GetFlatDistanceValue(range), 2), Length.LabelAbbr(range.Activity.Category.DistanceUnits));
            }

            return String.Empty;
        }

        public double GetDescentDistanceValue(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                ZoneCategoryInfo categoryInfo = ZoneCategoryInfo.Calculate(range.ActivityInfo, PluginMain.GetApplication().DisplayOptions.SelectedClimbZone, range.RangeGradeTrack, 100.0f);
                double totalDescentDistance = 0;

                // Remove totals row
                categoryInfo.Zones.RemoveAt(categoryInfo.Zones.Count - 1);

                foreach (ZoneInfo zoneInfo in categoryInfo.Zones)
                {
                    if (zoneInfo.Zone.High < 0)
                    {
                        totalDescentDistance += zoneInfo.TotalDistanceMeters;
                    }
                }

                return Length.Convert(totalDescentDistance, Length.Units.Meter, range.Activity.Category.DistanceUnits);
            }

            return 0;
        }

        public String GetDescentDistance(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                return String.Format("{0:0.00} {1}", Math.Round(GetDescentDistanceValue(range), 2), Length.LabelAbbr(range.Activity.Category.DistanceUnits));
            }

            return String.Empty;
        }

        public double GetMinSpeedValue(RangeWrapper range)
        {
            if (range.RangeSpeedTrack.Count > 0)
            {
                return Length.Convert(range.RangeSpeedTrack.Min, Length.Units.Meter, Utils.MajorLengthUnit(range.Activity.Category.DistanceUnits)) * Constants.SecondsPerHour;
            }

            return 0;
        }

        public String GetMinSpeed(RangeWrapper range)
        {
            if (range.RangeSpeedTrack.Count > 0)
            {
                return String.Format("{0:0.0}", GetMinSpeedValue(range));
            }

            return String.Empty;
        }

        public double GetAvgSpeedValue(RangeWrapper range)
        {
            if (range.RangeSpeedTrack.Count > 0)
            {
                return Length.Convert(range.RangeSpeedTrack.Avg, Length.Units.Meter, Utils.MajorLengthUnit(range.Activity.Category.DistanceUnits)) * Constants.SecondsPerHour;
            }

            return 0;
        }

        public String GetAvgSpeed(RangeWrapper range)
        {
            if (range.RangeSpeedTrack.Count > 0)
            {
                return String.Format("{0:0.0}", GetAvgSpeedValue(range));
            }

            return String.Empty;
        }

        public double GetMaxSpeedValue(RangeWrapper range)
        {
            if (range.RangeSpeedTrack.Count > 0)
            {
                return Length.Convert(range.RangeSpeedTrack.Max, Length.Units.Meter, Utils.MajorLengthUnit(range.Activity.Category.DistanceUnits)) * Constants.SecondsPerHour;
            }

            return 0;
        }

        public String GetMaxSpeed(RangeWrapper range)
        {
            if (range.RangeSpeedTrack.Count > 0)
            {
                return String.Format("{0:0.0}", GetMaxSpeedValue(range));
            }

            return String.Empty;
        }

        public double GetSpeedVsAvgValue(RangeWrapper range)
        {
            if (range.RangeSpeedTrack.Count > 0)
            {
                double speedVsAvg = range.RangeSpeedTrack.Avg - range.ActivitySpeedTrack.Avg;
                return Length.Convert(speedVsAvg, Length.Units.Meter, Utils.MajorLengthUnit(range.Activity.Category.DistanceUnits)) * Constants.SecondsPerHour;
            }

            return 0;
        }

        public String GetSpeedVsAvg(RangeWrapper range)
        {
            if (range.RangeSpeedTrack.Count > 0)
            {
                String sign = String.Empty;
                double value = GetSpeedVsAvgValue(range);

                if (value < 0)
                {
                    sign = "-";
                }
                else if (value > 0)
                {
                    sign = "+";
                }

                return String.Format("{1}{0:0.0}", Math.Abs(value), sign);
            }

            return String.Empty;
        }

        public double GetVerticalSpeedValue(RangeWrapper range)
        {
            if (range.RangeElevationTrack.Count > 0)
            {
                return GetElevationChangeValue(range) / GetElapsedTimeValue(range).TotalHours;
            }

            return 0;
        }

        public String GetVerticalSpeed(RangeWrapper range)
        {
            if (range.RangeElevationTrack.Count > 0)
            {
                String sign = String.Empty;
                double value = GetVerticalSpeedValue(range);

                if (value < 0)
                {
                    sign = "-";
                }
                else if (value > 0)
                {
                    sign = "+";
                }

                return String.Format("{1}{0:0.0} {2}/{3}", Math.Abs(value), sign, Length.LabelAbbr(range.Activity.Category.ElevationUnits), CommonResources.Text.LabelHour_lower);
            }

            return String.Empty;
        }

        public double GetMinCadenceValue(RangeWrapper range)
        {
            if (range.RangeCadenceTrack.Count > 0)
            {
                return range.RangeCadenceTrack.Min;
            }

            return 0;
        }

        public String GetMinCadence(RangeWrapper range)
        {
            if (range.RangeCadenceTrack.Count > 0)
            {
                return String.Format("{0:0.0}", GetMinCadenceValue(range));
            }

            return String.Empty;
        }

        public double GetAvgCadenceValue(RangeWrapper range)
        {
            if (range.RangeCadenceTrack.Count > 0)
            {
                return range.RangeCadenceTrack.Avg;
            }

            return 0;
        }

        public String GetAvgCadence(RangeWrapper range)
        {
            if (range.RangeCadenceTrack.Count > 0)
            {
                return String.Format("{0:0.0}", GetAvgCadenceValue(range));
            }

            return String.Empty;
        }

        public double GetMaxCadenceValue(RangeWrapper range)
        {
            if (range.RangeCadenceTrack.Count > 0)
            {
                return range.RangeCadenceTrack.Max;
            }

            return 0;
        }
        public String GetMaxCadence(RangeWrapper range)
        {
            if (range.RangeCadenceTrack.Count > 0)
            {
                return String.Format("{0:0.0}", GetMaxCadenceValue(range));
            }

            return String.Empty;
        }

        public double GetCadenceVsAvgValue(RangeWrapper range)
        {
            if (range.RangeCadenceTrack.Count > 0)
            {
                return range.RangeCadenceTrack.Avg - range.ActivityCadenceTrack.Avg;
            }

            return 0;
        }
        public String GetCadenceVsAvg(RangeWrapper range)
        {
            if (range.RangeCadenceTrack.Count > 0)
            {
                String sign = String.Empty;
                double value = GetCadenceVsAvgValue(range);

                if (value < 0)
                {
                    sign = "-";
                }
                else if (value > 0)
                {
                    sign = "+";
                }

                return String.Format("{1}{0:0.0}", Math.Abs(value), sign);
            }

            return String.Empty;
        }

        public double GetMinHRValue(RangeWrapper range)
        {
            if (range.RangeHeartRateTrack.Count > 0)
            {
                return range.RangeHeartRateTrack.Min;
            }

            return 0;
        }

        public String GetMinHR(RangeWrapper range)
        {
            if (range.RangeHeartRateTrack.Count > 0)
            {
                String percentMax = String.Empty;
                IAthleteInfoEntry lastAthleteEntry = PluginMain.GetApplication().Logbook.Athlete.InfoEntries.LastEntryAsOfDate(range.ActivityInfo.ActualTrackStart);

                // Value is in BPM so convert to the % max HR if we have the info
                if (!float.IsNaN(lastAthleteEntry.MaximumHeartRatePerMinute))
                {
                    percentMax = String.Format(" ({0:0}%)", GetMinHRValue(range) / lastAthleteEntry.MaximumHeartRatePerMinute * 100);
                }

                return String.Format("{0:0}{1}", GetMinHRValue(range), percentMax);
            }

            return String.Empty;
        }

        public double GetAvgHRValue(RangeWrapper range)
        {
            if (range.RangeHeartRateTrack.Count > 0)
            {
                return range.RangeHeartRateTrack.Avg;
            }

            return 0;
        }

        public String GetAvgHR(RangeWrapper range)
        {
            if (range.RangeHeartRateTrack.Count > 0)
            {
                String percentMax = String.Empty;
                IAthleteInfoEntry lastAthleteEntry = PluginMain.GetApplication().Logbook.Athlete.InfoEntries.LastEntryAsOfDate(range.ActivityInfo.ActualTrackStart);

                // Value is in BPM so convert to the % max HR if we have the info
                if (!float.IsNaN(lastAthleteEntry.MaximumHeartRatePerMinute))
                {
                    percentMax = String.Format(" ({0:0}%)", GetAvgHRValue(range) / lastAthleteEntry.MaximumHeartRatePerMinute * 100);
                }

                return String.Format("{0:0.0}{1}", GetAvgHRValue(range), percentMax);
            }

            return String.Empty;
        }

        public double GetMaxHRValue(RangeWrapper range)
        {
            if (range.RangeHeartRateTrack.Count > 0)
            {
                return range.RangeHeartRateTrack.Max;
            }

            return 0;
        }

        public String GetMaxHR(RangeWrapper range)
        {
            if (range.RangeHeartRateTrack.Count > 0)
            {
                String percentMax = String.Empty;
                IAthleteInfoEntry lastAthleteEntry = PluginMain.GetApplication().Logbook.Athlete.InfoEntries.LastEntryAsOfDate(range.ActivityInfo.ActualTrackStart);

                // Value is in BPM so convert to the % max HR if we have the info
                if (!float.IsNaN(lastAthleteEntry.MaximumHeartRatePerMinute))
                {
                    percentMax = String.Format(" ({0:0}%)", GetMaxHRValue(range) / lastAthleteEntry.MaximumHeartRatePerMinute * 100);
                }

                return String.Format("{0:0}{1}", GetMaxHRValue(range), percentMax);
            }

            return String.Empty;
        }

        public double GetHRVsAvgValue(RangeWrapper range)
        {
            if (range.RangeHeartRateTrack.Count > 0)
            {
                return range.RangeHeartRateTrack.Avg - range.ActivityHeartRateTrack.Avg;
            }

            return 0;
        }

        public String GetHRVsAvg(RangeWrapper range)
        {
            if (range.RangeHeartRateTrack.Count > 0)
            {
                String sign = String.Empty;
                double value = GetHRVsAvgValue(range);

                if (value < 0)
                {
                    sign = "-";
                }
                else if (value > 0)
                {
                    sign = "+";
                }

                return String.Format("{1}{0:0.0}", Math.Abs(value), sign);
            }

            return String.Empty;
        }

        public double GetMinGradeValue(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                return range.RangeGradeTrack.Min * 100.0f;
            }

            return 0;
        }

        public String GetMinGrade(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                return String.Format("{0:0.0}%", GetMinGradeValue(range));
            }

            return String.Empty;
        }

        public double GetAvgGradeValue(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                return range.RangeGradeTrack.Avg * 100.0f;
            }

            return 0;
        }

        public String GetAvgGrade(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                return String.Format("{0:0.0}%", GetAvgGradeValue(range));
            }

            return String.Empty;
        }

        public double GetAvgAscentGradeValue(RangeWrapper range)
        {
            if (range.RangeElevationTrack.Count > 0 && m_AscentDistance > 0)
            {
                return (GetTotalAscentValue() * 100) / GetAscentDistanceValue();
            }

            return 0;
        }

        public String GetAvgAscentGrade(RangeWrapper range)
        {
            if (range.RangeElevationTrack.Count > 0)
            {
                return String.Format("{0:0.0}%", Math.Round(GetAvgAscentGradeValue(range), 1));
            }

            return String.Empty;
        }

        public double GetAvgDescentGradeValue(RangeWrapper range)
        {
            if (range.RangeElevationTrack.Count > 0 && m_DescentDistance > 0)
            {
                return (GetTotalDescentValue() * 100) / GetDescentDistanceValue();
            }

            return 0;
        }

        public String GetAvgDescentGrade(RangeWrapper range)
        {
            if (range.RangeElevationTrack.Count > 0)
            {
                return String.Format("{0:0.0}%", Math.Round(GetAvgDescentGradeValue(range), 1));
            }

            return String.Empty;
        }

        public double GetMaxGradeValue(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                return range.RangeGradeTrack.Max * 100.0f;
            }

            return 0;
        }

        public String GetMaxGrade(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                return String.Format("{0:0.0}%", GetMaxGradeValue(range));
            }

            return String.Empty;
        }

        public double GetGradeVsAvgValue(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                return (range.RangeGradeTrack.Avg - range.ActivityGradeTrack.Avg) * 100.0f;
            }

            return 0;
        }

        public String GetGradeVsAvg(RangeWrapper range)
        {
            if (range.RangeGradeTrack.Count > 0)
            {
                String sign = String.Empty;
                double value = GetGradeVsAvgValue(range);

                if (value < 0)
                {
                    sign = "-";
                }
                else if (value > 0)
                {
                    sign = "+";
                }

                return String.Format("{1}{0:0.0}", Math.Abs(value), sign);
            }

            return String.Empty;
        }

        public double GetMinPowerValue(RangeWrapper range)
        {
            if (range.RangePowerTrack.Count > 0)
            {
                return range.RangePowerTrack.Min;
            }

            return 0;
        }

        public String GetMinPower(RangeWrapper range)
        {
            if (range.RangePowerTrack.Count > 0)
            {
                return String.Format("{0:0.0}", GetMinPowerValue(range));
            }

            return String.Empty;
        }

        public double GetAvgPowerValue(RangeWrapper range)
        {
            if (range.RangePowerTrack.Count > 0)
            {
                return range.RangePowerTrack.Avg;
            }

            return 0;
        }

        public String GetAvgPower(RangeWrapper range)
        {
            if (range.RangePowerTrack.Count > 0)
            {
                return String.Format("{0:0.0}", GetAvgPowerValue(range));
            }

            return String.Empty;
        }

        public double GetMaxPowerValue(RangeWrapper range)
        {
            if (range.RangePowerTrack.Count > 0)
            {
                return range.RangePowerTrack.Max;
            }

            return 0;
        }

        public String GetMaxPower(RangeWrapper range)
        {
            if (range.RangePowerTrack.Count > 0)
            {
                return String.Format("{0:0.0}", GetMaxPowerValue(range));
            }

            return String.Empty;
        }

        public double GetPowerVsAvgValue(RangeWrapper range)
        {
            if (range.RangePowerTrack.Count > 0)
            {
                return range.RangePowerTrack.Avg - range.ActivityPowerTrack.Avg;
            }

            return 0;
        }

        public String GetPowerVsAvg(RangeWrapper range)
        {
            if (range.RangePowerTrack.Count > 0)
            {
                String sign = String.Empty;
                double value = GetPowerVsAvgValue(range);

                if (value < 0)
                {
                    sign = "-";
                }
                else if (value > 0)
                {
                    sign = "+";
                }

                return String.Format("{1}{0:0.0}", Math.Abs(value), sign);
            }

            return String.Empty;
        }

#endregion

#region All ranges stats

        public String TotalStartTime
        {
            get
            {
                return String.Empty;
            }
        }

        public String TotalEndTime
        {
            get
            {
                return String.Empty;
            }
        }

        public String TotalStartDistance
        {
            get
            {
                return String.Empty;
            }
        }

        public String TotalEndDistance
        {
            get
            {
                return String.Empty;
            }
        }

        public String TotalElapsedTime
        {
            get
            {
                TimeSpan elapsedTime = new TimeSpan(0, 0, 0);

                foreach (RangeWrapper range in m_AllRanges)
                {
                    elapsedTime += GetElapsedTimeValue(range);
                }

                return String.Format("{0:00}:{1:00}:{2:00}", elapsedTime.Hours, elapsedTime.Minutes, elapsedTime.Seconds);
            }
        }

        public String TotalDistance
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.MovingDistanceMetersTrack.Count > 0)
                {
                    double distance = 0;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        distance += GetDistanceValue(range);
                    }

                    return String.Format("{0:0.00} {1}", distance, Length.LabelAbbr(m_AllRanges[0].Activity.Category.DistanceUnits));
                }

                return String.Empty;
            }
        }

        public double TotalTimePercentValue
        {
            get
            {
                double totalTimePercent = 0;

                foreach (RangeWrapper range in m_AllRanges)
                {
                    totalTimePercent += GetTimePercentValue(range);
                }

                return totalTimePercent;
            }
        }

        public String TotalTimePercent
        {
            get
            {
                if (TotalTimePercentValue != 0)
                {
                    return String.Format("{0:0.00} %", TotalTimePercentValue * 100.0);
                }

                return String.Empty;
            }
        }

        public double TotalDistancePercentValue
        {
            get
            {
                double totalDistancePercent = 0;

                foreach (RangeWrapper range in m_AllRanges)
                {
                    totalDistancePercent += GetDistancePercentValue(range);
                }

                return totalDistancePercent;
            }
        }

        public String TotalDistancePercent
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.MovingDistanceMetersTrack.Max > 0)
                {
                    return String.Format("{0:0.00} %", TotalDistancePercentValue * 100.0);
                }

                return String.Empty;
            }
        }

        public String TotalStartElevation
        {
            get
            {
                return String.Empty;
            }
        }

        public String TotalEndElevation
        {
            get
            {
                return String.Empty;
            }
        }

        public String TotalElevationChange
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    double elevationChange = 0;
                    String sign = String.Empty;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        elevationChange += GetElevationChangeValue(range);
                    }

                    if (elevationChange < 0)
                    {
                        sign = "-";
                    }
                    else if (elevationChange > 0)
                    {
                        sign = "+";
                    }

                    return String.Format("{2}{0:0.0} {1}", Math.Abs(elevationChange), Length.LabelAbbr(m_AllRanges[0].Activity.Category.ElevationUnits), sign);
                }

                return String.Empty;
            }
        }


        public double TotalTotalAscentValue
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    double totalAscent = 0;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        totalAscent += GetTotalAscentValue(range);
                    }

                    return totalAscent;
                }

                return 0;
            }
        }

        public String TotalTotalAscent
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    return String.Format("{0:0.0} {1}", Math.Round(TotalTotalAscentValue, 1), Length.LabelAbbr(m_AllRanges[0].Activity.Category.ElevationUnits));
                }

                return String.Empty;
            }
        }

        public double TotalTotalDescentValue
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    double totalDescent = 0;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        totalDescent += GetTotalDescentValue(range);
                    }

                    return totalDescent;
                }

                return 0;
            }
        }

        public String TotalTotalDescent
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    return String.Format("{0:0.0} {1}", Math.Round(TotalTotalDescentValue, 1), Length.LabelAbbr(m_AllRanges[0].Activity.Category.ElevationUnits));
                }

                return String.Empty;
            }
        }

        public double TotalAscentDistanceValue
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    double totalDistance = 0;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        totalDistance += GetAscentDistanceValue(range);
                    }

                    return totalDistance;
                }

                return 0;
            }
        }

        public String TotalAscentDistance
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    return String.Format("{0:0.00} {1}", Math.Round(TotalAscentDistanceValue, 2), Length.LabelAbbr(m_AllRanges[0].Activity.Category.DistanceUnits));
                }

                return String.Empty;
            }
        }

        public double TotalFlatDistanceValue
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    double totalDistance = 0;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        totalDistance += GetFlatDistanceValue(range);
                    }

                    return totalDistance;
                }

                return 0;
            }
        }

        public String TotalFlatDistance
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    return String.Format("{0:0.00} {1}", Math.Round(TotalFlatDistanceValue, 2), Length.LabelAbbr(m_AllRanges[0].Activity.Category.DistanceUnits));
                }

                return String.Empty;
            }
        }

        public double TotalDescentDistanceValue
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    double totalDistance = 0;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        totalDistance += GetDescentDistanceValue(range);
                    }

                    return totalDistance;
                }

                return 0;
            }
        }

        public String TotalDescentDistance
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    return String.Format("{0:0.00} {1}", Math.Round(TotalDescentDistanceValue, 2), Length.LabelAbbr(m_AllRanges[0].Activity.Category.DistanceUnits));
                }

                return String.Empty;
            }
        }

        public String TotalMinSpeed
        {
            get
            {
                if (m_AllRanges[0].ActivitySpeedTrack.Count > 0)
                {
                    double min = Length.Convert(m_AllRanges[0].ActivitySpeedTrack.Max, Length.Units.Meter, Utils.MajorLengthUnit(m_AllRanges[0].Activity.Category.DistanceUnits)) * Constants.SecondsPerHour;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        min = Math.Min(min, GetMinSpeedValue(range));
                    }

                    return String.Format("{0:0.0}", min);
                }

                return String.Empty;
            }
        }

        public double TotalAvgSpeedValue
        {
            get
            {
                double avg = 0;

                foreach (RangeWrapper range in m_AllRanges)
                {
                    avg += GetAvgSpeedValue(range) * GetTimePercentValue(range);
                }

                return avg / TotalTimePercentValue;
            }
        }

        public String TotalAvgSpeed
        {
            get
            {
                if (m_AllRanges[0].ActivitySpeedTrack.Count > 0)
                {
                    return String.Format("{0:0.0}", TotalAvgSpeedValue);
                }

                return String.Empty;
            }
        }

        public String TotalMaxSpeed
        {
            get
            {
                if (m_AllRanges[0].ActivitySpeedTrack.Count > 0)
                {
                    double max = 0;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        max = Math.Max(max, GetMaxSpeedValue(range));
                    }

                    return String.Format("{0:0.0}", max);
                }

                return String.Empty;
            }
        }

        public String TotalSpeedVsAvg
        {
            get
            {
                if (m_AllRanges[0].ActivitySpeedTrack.Count > 0)
                {
                    double speedVsAvg = TotalAvgSpeedValue - Length.Convert(m_AllRanges[0].ActivitySpeedTrack.Avg, Length.Units.Meter, Utils.MajorLengthUnit(m_AllRanges[0].Activity.Category.DistanceUnits)) * Constants.SecondsPerHour;
                    String sign = String.Empty;

                    if (speedVsAvg < 0)
                    {
                        sign = "-";
                    }
                    else if (speedVsAvg > 0)
                    {
                        sign = "+";
                    }

                    return String.Format("{1}{0:0.0}", Math.Abs(speedVsAvg), sign);
                }

                return String.Empty;
            }
        }

        public double TotalVerticalSpeedValue
        {
            get
            {
                double avg = 0;

                foreach (RangeWrapper range in m_AllRanges)
                {
                    avg += GetVerticalSpeedValue(range) * GetTimePercentValue(range);
                }

                return avg / TotalTimePercentValue;
            }
        }

        public String TotalVerticalSpeed
        {
            get
            {
                if (m_AllRanges[0].ActivityElevationTrack.Count > 0)
                {
                    String sign = String.Empty;

                    if (TotalVerticalSpeedValue < 0)
                    {
                        sign = "-";
                    }
                    else if (TotalVerticalSpeedValue > 0)
                    {
                        sign = "+";
                    }

                    return String.Format("{1}{0:0.0} {2}/{3}", Math.Abs(TotalVerticalSpeedValue), sign, Length.LabelAbbr(m_AllRanges[0].Activity.Category.ElevationUnits), CommonResources.Text.LabelHour_lower);
                }

                return String.Empty;
            }
        }

        public String TotalMinCadence
        {
            get
            {
                if (m_AllRanges[0].ActivityCadenceTrack.Count > 0)
                {
                    double min = m_AllRanges[0].ActivityCadenceTrack.Max;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        min = Math.Min(min, GetMinCadenceValue(range));
                    }

                    return String.Format("{0:0.0}", min);
                }

                return String.Empty;
            }
        }

        public double TotalAvgCadenceValue
        {
            get
            {
                double avg = 0;

                foreach (RangeWrapper range in m_AllRanges)
                {
                    avg += GetAvgCadenceValue(range) * GetTimePercentValue(range);
                }

                return avg / TotalTimePercentValue;
            }
        }

        public String TotalAvgCadence
        {
            get
            {
                if (m_AllRanges[0].ActivityCadenceTrack.Count > 0)
                {
                    return String.Format("{0:0.0}", TotalAvgCadenceValue);
                }

                return String.Empty;
            }
        }

        public String TotalMaxCadence
        {
            get
            {
                if (m_AllRanges[0].ActivityCadenceTrack.Count > 0)
                {
                    double max = 0;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        max = Math.Max(max, GetMaxCadenceValue(range));
                    }

                    return String.Format("{0:0.0}", max);
                }

                return String.Empty;
            }
        }

        public String TotalCadenceVsAvg
        {
            get
            {
                if (m_AllRanges[0].ActivityCadenceTrack.Count > 0)
                {
                    double cadenceVsAvg = TotalAvgCadenceValue - m_AllRanges[0].ActivityCadenceTrack.Avg;
                    String sign = String.Empty;

                    if (cadenceVsAvg < 0)
                    {
                        sign = "-";
                    }
                    else if (cadenceVsAvg > 0)
                    {
                        sign = "+";
                    }

                    return String.Format("{1}{0:0.0}", Math.Abs(cadenceVsAvg), sign);
                }

                return String.Empty;
            }
        }

        public String TotalMinHR
        {
            get
            {
                if (m_AllRanges[0].ActivityHeartRateTrack.Count > 0)
                {
                    double min = m_AllRanges[0].ActivityHeartRateTrack.Max;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        min = Math.Min(min, GetMinHRValue(range));
                    }

                    String percentMax = String.Empty;
                    IAthleteInfoEntry lastAthleteEntry = PluginMain.GetApplication().Logbook.Athlete.InfoEntries.LastEntryAsOfDate(m_AllRanges[0].ActivityInfo.ActualTrackStart);

                    // Value is in BPM so convert to the % max HR if we have the info
                    if (!float.IsNaN(lastAthleteEntry.MaximumHeartRatePerMinute))
                    {
                        percentMax = String.Format(" ({0:0}%)", min / lastAthleteEntry.MaximumHeartRatePerMinute * 100);
                    }

                    return String.Format("{0:0}{1}", min, percentMax);
                }

                return String.Empty;
            }
        }

        public double TotalAvgHRValue
        {
            get
            {
                double avg = 0;

                foreach (RangeWrapper range in m_AllRanges)
                {
                    avg += GetAvgHRValue(range) * GetTimePercentValue(range);
                }

                return avg / TotalTimePercentValue;
            }
        }

        public String TotalAvgHR
        {
            get
            {
                if (m_AllRanges[0].ActivityHeartRateTrack.Count > 0)
                {
                    double avg = TotalAvgHRValue;
                    String percentMax = String.Empty;
                    IAthleteInfoEntry lastAthleteEntry = PluginMain.GetApplication().Logbook.Athlete.InfoEntries.LastEntryAsOfDate(m_AllRanges[0].ActivityInfo.ActualTrackStart);

                    // Value is in BPM so convert to the % max HR if we have the info
                    if (!float.IsNaN(lastAthleteEntry.MaximumHeartRatePerMinute))
                    {
                        percentMax = String.Format(" ({0:0}%)", avg / lastAthleteEntry.MaximumHeartRatePerMinute * 100);
                    }

                    return String.Format("{0:0.0}{1}", avg, percentMax);
                }

                return String.Empty;
            }
        }

        public String TotalMaxHR
        {
            get
            {
                if (m_AllRanges[0].ActivityHeartRateTrack.Count > 0)
                {
                    double max = 0;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        max = Math.Max(max, GetMaxHRValue(range));
                    }

                    String percentMax = String.Empty;
                    IAthleteInfoEntry lastAthleteEntry = PluginMain.GetApplication().Logbook.Athlete.InfoEntries.LastEntryAsOfDate(m_AllRanges[0].ActivityInfo.ActualTrackStart);

                    // Value is in BPM so convert to the % max HR if we have the info
                    if (!float.IsNaN(lastAthleteEntry.MaximumHeartRatePerMinute))
                    {
                        percentMax = String.Format(" ({0:0}%)", max / lastAthleteEntry.MaximumHeartRatePerMinute * 100);
                    }

                    return String.Format("{0:0}{1}", max, percentMax);
                }

                return String.Empty;
            }
        }

        public String TotalHRVsAvg
        {
            get
            {
                if (m_AllRanges[0].ActivityHeartRateTrack.Count > 0)
                {
                    double HRVsAvg = TotalAvgHRValue - m_AllRanges[0].ActivityHeartRateTrack.Avg;
                    String sign = String.Empty;

                    if (HRVsAvg < 0)
                    {
                        sign = "-";
                    }
                    else if (HRVsAvg > 0)
                    {
                        sign = "+";
                    }

                    return String.Format("{1}{0:0.0}", Math.Abs(HRVsAvg), sign);
                }

                return String.Empty;
            }
        }

        public String TotalMinGrade
        {
            get
            {
                if (m_AllRanges[0].ActivityGradeTrack.Count > 0)
                {
                    double min = m_AllRanges[0].ActivityGradeTrack.Max * 100;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        min = Math.Min(min, GetMinGradeValue(range));
                    }

                    return String.Format("{0:0.0}%", min);
                }

                return String.Empty;
            }
        }

        public double TotalAvgGradeValue
        {
            get
            {
                double avg = 0;

                foreach (RangeWrapper range in m_AllRanges)
                {
                    avg += GetAvgGradeValue(range) * GetDistancePercentValue(range);
                }

                return avg / TotalDistancePercentValue;
            }
        }

        public String TotalAvgGrade
        {
            get
            {
                if (m_AllRanges[0].ActivityGradeTrack.Count > 0)
                {
                    return String.Format("{0:0.0}%", TotalAvgGradeValue);
                }

                return String.Empty;
            }
        }

        public double TotalAvgAscentGradeValue
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    double totalAscent = 0;
                    double totalDistance = 0;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        totalAscent += GetTotalAscentValue(range);
                        totalDistance += GetAscentDistanceValue(range);
                    }

                    if (totalDistance > 0)
                    {
                        return (totalAscent * 100) / Length.Convert(totalDistance, m_AllRanges[0].Activity.Category.DistanceUnits, m_AllRanges[0].Activity.Category.ElevationUnits);
                    }
                }

                return 0;
            }
        }

        public String TotalAvgAscentGrade
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    return String.Format("{0:0.0}%", Math.Round(TotalAvgAscentGradeValue, 1));
                }

                return String.Empty;
            }
        }

        public double TotalAvgDescentGradeValue
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    double totalDescent = 0;
                    double totalDistance = 0;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        totalDescent += GetTotalDescentValue(range);
                        totalDistance += GetDescentDistanceValue(range);
                    }

                    if (totalDistance > 0)
                    {
                        return (totalDescent * 100) / Length.Convert(totalDistance, m_AllRanges[0].Activity.Category.DistanceUnits, m_AllRanges[0].Activity.Category.ElevationUnits);
                    }
                }

                return 0;
            }
        }

        public String TotalAvgDescentGrade
        {
            get
            {
                if (m_AllRanges[0].ActivityInfo.SmoothedElevationTrack.Count > 0)
                {
                    return String.Format("{0:0.0}%", Math.Round(TotalAvgDescentGradeValue, 1));
                }

                return String.Empty;
            }
        }

        public String TotalMaxGrade
        {
            get
            {
                if (m_AllRanges[0].ActivityGradeTrack.Count > 0)
                {
                    double max = m_AllRanges[0].ActivityGradeTrack.Min * 100.0f;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        max = Math.Max(max, GetMaxGradeValue(range));
                    }

                    return String.Format("{0:0.0}%", max);
                }

                return String.Empty;
            }
        }

        public String TotalGradeVsAvg
        {
            get
            {
                if (m_AllRanges[0].ActivityGradeTrack.Count > 0)
                {
                    double gradeVsAvg = TotalAvgGradeValue - (m_AllRanges[0].ActivityGradeTrack.Avg * 100.0f);
                    String sign = String.Empty;

                    if (gradeVsAvg < 0)
                    {
                        sign = "-";
                    }
                    else if (gradeVsAvg > 0)
                    {
                        sign = "+";
                    }

                    return String.Format("{1}{0:0.0}", Math.Abs(gradeVsAvg), sign);
                }

                return String.Empty;
            }
        }

        public String TotalMinPower
        {
            get
            {
                if (m_AllRanges[0].ActivityPowerTrack.Count > 0)
                {
                    double min = m_AllRanges[0].ActivityPowerTrack.Max;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        min = Math.Min(min, GetMinPowerValue(range));
                    }

                    return String.Format("{0:0.0}", min);
                }

                return String.Empty;
            }
        }

        public double TotalAvgPowerValue
        {
            get
            {
                double avg = 0;

                foreach (RangeWrapper range in m_AllRanges)
                {
                    avg += GetAvgPowerValue(range) * GetTimePercentValue(range);
                }

                return avg / TotalTimePercentValue;
            }
        }

        public String TotalAvgPower
        {
            get
            {
                if (m_AllRanges[0].ActivityPowerTrack.Count > 0)
                {
                    return String.Format("{0:0.0}", TotalAvgPowerValue);
                }

                return String.Empty;
            }
        }

        public String TotalMaxPower
        {
            get
            {
                if (m_AllRanges[0].ActivityPowerTrack.Count > 0)
                {
                    double max = m_AllRanges[0].ActivityPowerTrack.Min;

                    foreach (RangeWrapper range in m_AllRanges)
                    {
                        max = Math.Max(max, GetMaxPowerValue(range));
                    }

                    return String.Format("{0:0.0}", max);
                }

                return String.Empty;
            }
        }

        public String TotalPowerVsAvg
        {
            get
            {
                if (m_AllRanges[0].ActivityPowerTrack.Count > 0)
                {
                    double powerVsAvg = TotalAvgPowerValue - m_AllRanges[0].ActivityPowerTrack.Avg;
                    String sign = String.Empty;

                    if (powerVsAvg < 0)
                    {
                        sign = "-";
                    }
                    else if (powerVsAvg > 0)
                    {
                        sign = "+";
                    }

                    return String.Format("{1}{0:0.0}", Math.Abs(powerVsAvg), sign);
                }

                return String.Empty;
            }
        }

#endregion

        public void RegisterColumns(TreeListColumnManager manager)
        {
            manager.RegisterColumn(new Guid("31c2df34-39a5-4496-8adc-2674caee1b76"), this, CommonResources.Text.LabelStartTime, PluginMain.GetApplication().VisualTheme.ControlText);
            manager.RegisterColumn(new Guid("fb860869-29ff-4ae5-b748-8b68c6d6b362"), this, CommonResources.Text.LabelEndTime, PluginMain.GetApplication().VisualTheme.ControlText);
            manager.RegisterColumn(new Guid("dd64616e-c5d4-487d-935a-935d4f8a7c01"), this, CommonResources.Text.LabelTime, PluginMain.GetApplication().VisualTheme.ControlText);
            manager.RegisterColumn(new Guid("ab3da546-8363-4e07-9e05-630b2d4e77df"), this, PluginView.GetLocalizedString("StartDistanceText"), PluginMain.GetApplication().VisualTheme.ControlText);
            manager.RegisterColumn(new Guid("94a7f1dc-fb2e-47c0-a8bc-fc33684f64b4"), this, PluginView.GetLocalizedString("EndDistanceText"), PluginMain.GetApplication().VisualTheme.ControlText);
            manager.RegisterColumn(new Guid("9fee353d-5695-4ef8-9d40-5b8684b83a97"), this, CommonResources.Text.LabelDistance, PluginMain.GetApplication().VisualTheme.ControlText);
            manager.RegisterColumn(new Guid("6b21c28d-45d3-4129-9c31-a360593e7449"), this, PluginView.GetLocalizedString("TimePercentText"), PluginMain.GetApplication().VisualTheme.ControlText);
            manager.RegisterColumn(new Guid("0a38f45f-78db-470c-a258-49a5bfc47d16"), this, PluginView.GetLocalizedString("DistancePercentText"), PluginMain.GetApplication().VisualTheme.ControlText);
            manager.RegisterColumn(new Guid("4729b986-a86b-4c4b-a280-b28c62773c22"), this, PluginView.GetLocalizedString("StartElevationText"), Constants.LineChartTypesColors[1]);
            manager.RegisterColumn(new Guid("63844936-c14e-44b5-81f8-b16ed67b9560"), this, PluginView.GetLocalizedString("EndElevationText"), Constants.LineChartTypesColors[1]);
            manager.RegisterColumn(new Guid("1b06055e-c232-4383-9d43-50e558a69af1"), this, CommonResources.Text.LabelElevationChange, Constants.LineChartTypesColors[1]);
            manager.RegisterColumn(new Guid("30145d7d-67c1-4093-b461-312db69d8d1f"), this, PluginView.GetLocalizedString("TotalAscentText"), Constants.LineChartTypesColors[1]);
            manager.RegisterColumn(new Guid("ec36c785-0a0b-4162-a8f8-66807bab182b"), this, PluginView.GetLocalizedString("TotalDescentText"), Constants.LineChartTypesColors[1]);
            manager.RegisterColumn(new Guid("9ca8d4ff-7373-4c82-a731-99a4bda0805b"), this, PluginView.GetLocalizedString("AscentDistanceText"), PluginMain.GetApplication().VisualTheme.ControlText);
            manager.RegisterColumn(new Guid("36f52593-cc7b-4249-b3fb-1378980745bc"), this, PluginView.GetLocalizedString("FlatDistanceText"), PluginMain.GetApplication().VisualTheme.ControlText);
            manager.RegisterColumn(new Guid("defc80b5-faee-42d2-b645-4ade3a1670d6"), this, PluginView.GetLocalizedString("DescentDistanceText"), PluginMain.GetApplication().VisualTheme.ControlText);
            manager.RegisterColumn(new Guid("7efdb968-97ba-4fef-9db1-bb3e7e1486e7"), this, PluginView.GetLocalizedString("MinSpeedText"), Constants.LineChartTypesColors[5]);
            manager.RegisterColumn(new Guid("76e38cb6-b1e9-46e6-9e95-6f529af9f0e6"), this, CommonResources.Text.LabelAvgSpeed, Constants.LineChartTypesColors[5]);
            manager.RegisterColumn(new Guid("1b5165e8-db42-428d-94ad-be18f19c6273"), this, PluginView.GetLocalizedString("MaxSpeedText"), Constants.LineChartTypesColors[5]);
            manager.RegisterColumn(new Guid("0c26ece5-b299-4a46-8a52-6e0f1c89fb8b"), this, CommonResources.Text.LabelSpeedVsAverage, Constants.LineChartTypesColors[5]);
            manager.RegisterColumn(new Guid("344c4d17-da2e-4b79-b2e2-d7362d74feaa"), this, PluginView.GetLocalizedString("VerticalSpeedText"), Constants.LineChartTypesColors[5]);
            manager.RegisterColumn(new Guid("72a37849-3d55-457b-8cc1-a87206104261"), this, PluginView.GetLocalizedString("MinCadenceText"), Constants.LineChartTypesColors[0]);
            manager.RegisterColumn(new Guid("a5eb53c6-3b4d-4b3e-884f-065d0b97d873"), this, CommonResources.Text.LabelAvgCadence, Constants.LineChartTypesColors[0]);
            manager.RegisterColumn(new Guid("4f37ed62-395d-4744-9d3f-6b4a28f6aa4e"), this, CommonResources.Text.LabelMaxCadence, Constants.LineChartTypesColors[0]);
            manager.RegisterColumn(new Guid("75800fd9-a35a-4f89-84c2-afcab9c906fa"), this, PluginView.GetLocalizedString("CadenceVsAvgText"), Constants.LineChartTypesColors[0]);
            manager.RegisterColumn(new Guid("dda8fcc6-3af6-4cf5-8a6e-b89a8ea12a2e"), this, PluginView.GetLocalizedString("MinHRText"), Constants.LineChartTypesColors[3]);
            manager.RegisterColumn(new Guid("a5b8217a-f593-4d6f-8901-16aa2c33ade0"), this, CommonResources.Text.LabelAvgHR, Constants.LineChartTypesColors[3]);
            manager.RegisterColumn(new Guid("fa1ab8ef-9dd3-4c17-97e1-2e64d8678cea"), this, CommonResources.Text.LabelMaxHR, Constants.LineChartTypesColors[3]);
            manager.RegisterColumn(new Guid("bf0555f8-ec23-47e1-b03a-c73ff26780fb"), this, PluginView.GetLocalizedString("HRVsAvgText"), Constants.LineChartTypesColors[3]);
            manager.RegisterColumn(new Guid("d3187244-d571-4e8d-9d58-c3a16b9a98cf"), this, PluginView.GetLocalizedString("MinPowerText"), Constants.LineChartTypesColors[4]);
            manager.RegisterColumn(new Guid("550e262d-2563-4131-9f37-04ceda1a8097"), this, PluginView.GetLocalizedString("AvgPowerText"), Constants.LineChartTypesColors[4]);
            manager.RegisterColumn(new Guid("62aa7fca-e9b4-4ae9-8411-e01511ac55a7"), this, CommonResources.Text.LabelMaxPower, Constants.LineChartTypesColors[4]);
            manager.RegisterColumn(new Guid("76695911-807c-44cc-ac7a-3367184db00e"), this, PluginView.GetLocalizedString("PowerVsAvgText"), Constants.LineChartTypesColors[4]);
            manager.RegisterColumn(new Guid("c2c92402-2c1c-4339-b5bd-981842d8cb8f"), this, PluginView.GetLocalizedString("MinGradeText"), Constants.LineChartTypesColors[2]);
            manager.RegisterColumn(new Guid("57521cfe-edf2-4bc0-a654-7ea79872c8ab"), this, PluginView.GetLocalizedString("AvgGradeText"), Constants.LineChartTypesColors[2]);
            manager.RegisterColumn(new Guid("3210bbff-605b-4978-abca-4f336a2268b0"), this, PluginView.GetLocalizedString("AvgAscentGradeText"), Constants.LineChartTypesColors[2]);
            manager.RegisterColumn(new Guid("c92dee39-2170-44df-8d21-9eddd816bd3b"), this, PluginView.GetLocalizedString("AvgDescentGradeText"), Constants.LineChartTypesColors[2]);
            manager.RegisterColumn(new Guid("d029aa4b-1d65-4033-b57c-d1dce27b573a"), this, PluginView.GetLocalizedString("MaxGradeText"), Constants.LineChartTypesColors[2]);
            manager.RegisterColumn(new Guid("b4b2ff41-507f-4d0e-85c7-94d5f135a147"), this, PluginView.GetLocalizedString("GradeVsAvgText"), Constants.LineChartTypesColors[2]);
        }

        public static Guid GuidFromValueMember(String valueMember)
        {
            if (valueMember == "StartTime")
            {
                return new Guid("31c2df34-39a5-4496-8adc-2674caee1b76");
            }
            else if (valueMember == "EndTime")
            {
                return new Guid("fb860869-29ff-4ae5-b748-8b68c6d6b362");
            }
            else if (valueMember == "ElapsedTime")
            {
                return new Guid("dd64616e-c5d4-487d-935a-935d4f8a7c01");
            }
            else if (valueMember == "StartDistance")
            {
                return new Guid("ab3da546-8363-4e07-9e05-630b2d4e77df");
            }
            else if (valueMember == "EndDistance")
            {
                return new Guid("94a7f1dc-fb2e-47c0-a8bc-fc33684f64b4");
            }
            else if (valueMember == "Distance")
            {
                return new Guid("9fee353d-5695-4ef8-9d40-5b8684b83a97");
            }
            else if (valueMember == "TimePercent")
            {
                return new Guid("6b21c28d-45d3-4129-9c31-a360593e7449");
            }
            else if (valueMember == "DistancePercent")
            {
                return new Guid("0a38f45f-78db-470c-a258-49a5bfc47d16");
            }
            else if (valueMember == "StartElevation")
            {
                return new Guid("4729b986-a86b-4c4b-a280-b28c62773c22");
            }
            else if (valueMember == "EndElevation")
            {
                return new Guid("63844936-c14e-44b5-81f8-b16ed67b9560");
            }
            else if (valueMember == "ElevationChange")
            {
                return new Guid("1b06055e-c232-4383-9d43-50e558a69af1");
            }
            else if (valueMember == "TotalAscent")
            {
                return new Guid("30145d7d-67c1-4093-b461-312db69d8d1f");
            }
            else if (valueMember == "TotalDescent")
            {
                return new Guid("ec36c785-0a0b-4162-a8f8-66807bab182b");
            }
            else if (valueMember == "AscentDistance")
            {
                return new Guid("9ca8d4ff-7373-4c82-a731-99a4bda0805b");
            }
            else if (valueMember == "FlatDistance")
            {
                return new Guid("36f52593-cc7b-4249-b3fb-1378980745bc");
            }
            else if (valueMember == "DescentDistance")
            {
                return new Guid("defc80b5-faee-42d2-b645-4ade3a1670d6");
            }
            else if (valueMember == "MinSpeed")
            {
                return new Guid("7efdb968-97ba-4fef-9db1-bb3e7e1486e7");
            }
            else if (valueMember == "AvgSpeed")
            {
                return new Guid("76e38cb6-b1e9-46e6-9e95-6f529af9f0e6");
            }
            else if (valueMember == "MaxSpeed")
            {
                return new Guid("1b5165e8-db42-428d-94ad-be18f19c6273");
            }
            else if (valueMember == "SpeedVsAvg")
            {
                return new Guid("0c26ece5-b299-4a46-8a52-6e0f1c89fb8b");
            }
            else if (valueMember == "VerticalSpeed")
            {
                return new Guid("344c4d17-da2e-4b79-b2e2-d7362d74feaa");
            }
            else if (valueMember == "MinCadence")
            {
                return new Guid("72a37849-3d55-457b-8cc1-a87206104261");
            }
            else if (valueMember == "AvgCadence")
            {
                return new Guid("a5eb53c6-3b4d-4b3e-884f-065d0b97d873");
            }
            else if (valueMember == "MaxCadence")
            {
                return new Guid("4f37ed62-395d-4744-9d3f-6b4a28f6aa4e");
            }
            else if (valueMember == "CadenceVsAvg")
            {
                return new Guid("75800fd9-a35a-4f89-84c2-afcab9c906fa");
            }
            else if (valueMember == "MinHR")
            {
                return new Guid("dda8fcc6-3af6-4cf5-8a6e-b89a8ea12a2e");
            }
            else if (valueMember == "AvgHR")
            {
                return new Guid("a5b8217a-f593-4d6f-8901-16aa2c33ade0");
            }
            else if (valueMember == "MaxHR")
            {
                return new Guid("fa1ab8ef-9dd3-4c17-97e1-2e64d8678cea");
            }
            else if (valueMember == "HRVsAvg")
            {
                return new Guid("bf0555f8-ec23-47e1-b03a-c73ff26780fb");
            }
            else if (valueMember == "MinPower")
            {
                return new Guid("d3187244-d571-4e8d-9d58-c3a16b9a98cf");
            }
            else if (valueMember == "AvgPower")
            {
                return new Guid("550e262d-2563-4131-9f37-04ceda1a8097");
            }
            else if (valueMember == "MaxPower")
            {
                return new Guid("62aa7fca-e9b4-4ae9-8411-e01511ac55a7");
            }
            else if (valueMember == "PowerVsAvg")
            {
                return new Guid("76695911-807c-44cc-ac7a-3367184db00e");
            }
            else if (valueMember == "MinGrade")
            {
                return new Guid("c2c92402-2c1c-4339-b5bd-981842d8cb8f");
            }
            else if (valueMember == "AvgGrade")
            {
                return new Guid("57521cfe-edf2-4bc0-a654-7ea79872c8ab");
            }
            else if (valueMember == "AvgAscentGrade")
            {
                return new Guid("3210bbff-605b-4978-abca-4f336a2268b0");
            }
            else if (valueMember == "AvgDescentGrade")
            {
                return new Guid("c92dee39-2170-44df-8d21-9eddd816bd3b");
            }
            else if (valueMember == "MaxGrade")
            {
                return new Guid("d029aa4b-1d65-4033-b57c-d1dce27b573a");
            }
            else if (valueMember == "GradeVsAvg")
            {
                return new Guid("b4b2ff41-507f-4d0e-85c7-94d5f135a147");
            }

            return Guid.Empty;
        }

        public static Color GetColumnColorFromId(string id)
        {
            // Simple string lookup works pretty good, so keep it simple but beware
            //  if adding columns
            if (id.Contains("Cadence"))
            {
                return Constants.LineChartTypesColors[0];
            }
            else if (id.Contains("Grade"))
            {
                return Constants.LineChartTypesColors[2];
            }
            else if (id.Contains("HR"))
            {
                return Constants.LineChartTypesColors[3];
            }
            else if (id.Contains("Power"))
            {
                return Constants.LineChartTypesColors[5];
            }
            else if (id.Contains("Speed"))
            {
                return Constants.LineChartTypesColors[6];
            }

            return Color.Black;
        }

        List<RangeWrapper> m_AllRanges = null;

        double m_TotalAscent = 0;
        double m_TotalDescent = 0;
        double m_AscentDistance = 0;
        double m_FlatDistance = 0;
        double m_DescentDistance = 0;

        bool m_ExtraStatsCached = false;
    }
}